package com.novunda.platform.common.repositories;

import com.novunda.platform.common.web.modal.Page;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.transform.ResultTransformer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;

import java.io.Serializable;
import java.util.List;

/**
 * @author linfeng
 * @since 2016/8/29
 */
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable>
        extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

    /**
     * 获取 Session
     */
    Session getSession();


        /**
     * 清除缓存数据
     */
    void clear();

    // -------------- QL Query --------------

    /**
     * QL 分页查询
     * @param page 分页对象
     * @param qlString hql语句
     * @param parameter 参数
     * @return 分页对象
     */
    <E> Page<E> find(Page<E> page, String qlString, Object... parameter);

    /**
     * QL 查询
     * @param qlString hql语句
     * @param parameter 参数
     * @return 分页对象
     */
    <E> List<E> find(String qlString, Object... parameter);

    /**
     * QL 更新
     * @param qlString hql语句
     * @param parameter 参数
     * @return 受影响行数
     */
    int update(String qlString, Object... parameter);

    /**
     * 创建 QL 查询对象
     * @param sqlString sqlString
     * @param parameter 参数
     * @return 查询对象
     */
    Query createQuery(String qlString, Object... parameter);

    // -------------- SQL Query --------------

    /**
     * SQL 分页查询
     * @param page page
     * @param sqlString sqlString
     * @param parameter 参数
     * @return 分页对象
     */
    <E> Page<E> findBySql(Page<E> page, String sqlString, Object... parameter);

    /**
     * SQL 分页查询
     * @param page page
     * @param sqlString sqlString
     * @param resultClass resultClass
     * @param parameter 参数
     * @return 分页对象
     */
    <E> Page<E> findBySql(Page<E> page, String sqlString, Class<?> resultClass, Object... parameter);

    /**
     * SQL 查询
     * @param sqlString sql
     * @param parameter 参数
     * @return 查询对象
     */
    <E> List<E> findBySql(String sqlString, Object... parameter);

    /**
     * SQL 查询
     * @param sqlString
     * @param resultClass
     * @param parameter
     * @return
     */
    <E> List<E> findBySql(String sqlString, Class<?> resultClass, Object... parameter);

    /**
     * SQL 更新
     * @param sqlString sql
     * @param parameter 参数
     * @return 查询对象
     */
    int updateBySql(String sqlString, Object... parameter);

    /**
     * 创建 SQL 查询对象
     * @param sqlString sql
     * @param parameter 参数
     * @return 查询对象
     */
    Query createSqlQuery(String sqlString, Object... parameter);

    // -------------- Criteria --------------

    /**
     * 分页查询
     * @param Pagination
     * @return
     */
    Page<T> find(Page<T> page);

    /**
     * 使用检索标准对象分页查询
     * @param page page
     * @param detachedCriteria detachedCriteria
     * @return  Pagination
     */
    Page<T> find(Page<T> page, DetachedCriteria detachedCriteria);

    /**
     * 使用检索标准对象分页查询
     * @param page page
     * @param detachedCriteria detachedCriteria
     * @param resultTransformer resultTransformer
     * @return 分页对象
     */
    Page<T> find(Page<T> page, DetachedCriteria detachedCriteria, ResultTransformer resultTransformer);

    /**
     * 使用检索标准对象查询
     * @param detachedCriteria detachedCriteria
     * @return 对象集合
     */
    List<T> find(DetachedCriteria detachedCriteria);

    /**
     * 使用检索标准对象查询
     * @param detachedCriteria 检索条件对象
     * @param resultTransformer transform
     * @return 对象集合
     */
    List<T> find(DetachedCriteria detachedCriteria, ResultTransformer resultTransformer);

    /**
     * 使用检索标准对象查询记录数
     * @param detachedCriteria 检索条件对象
     * @return 记录总数
     */
    long count(DetachedCriteria detachedCriteria);

    /**
     * 创建与会话无关的检索标准对象
     * @param criterions Restrictions.eq("name", value);
     * @return hibernate检索对象
     */
    DetachedCriteria createDetachedCriteria(Criterion... criterions);

    /**
     *  未激活账户数
     * @param detachedCriteria 检索条件对象
     * @return 未激活账户数
     */
    int queryNotActivateUser(DetachedCriteria detachedCriteria);

    /**
     *  激活账户数
     * @param detachedCriteria 检索条件对象
     * @return 激活账户数
     */
    int queryActivateUser(DetachedCriteria detachedCriteria);

    long findCertificateStatus(DetachedCriteria detachedCriteria);
}
